﻿using Aliphant.Mvvm.XEvent.Events;
using Aliphant.Mvvm.XEvent.UI;
using CommonLibrary.Helper;
using CommonLibrary.UI;
using CuteWallpaperDemo.Managers;
using CuteWallpaperDemo.Models;
using DataModel.Contants;
using DataModel.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Input;
using Size = System.Drawing.Size;

namespace CuteWallpaperDemo.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private ProjectAgent _projectAgent;
        private WindowEvent _windowEvent;
        private Timer timer;
        private int wp_index = 0;
        private bool _isExpend;
        private object locker = new object();
        private WallpaperManager wallpaperManager = new WallpaperManager();

        public MainWindowViewModel()
        {
            _settings = ConfigManager.Instance.Settings;

            _projectAgent = ProjectContainer.ProjectAgent;
            _windowEvent = _projectAgent.EventManager.GetEvent<WindowEvent>();

            timer = new Timer();
            timer.Interval = ConfigManager.Instance.Settings.PlaySetting.Interval * 1000;
            timer.AutoReset = true;
            timer.Elapsed += ChangeWallpaper;
            timer.Start();
            timer.Enabled = false;

            PlayBtnText = "播放";
            DropText = "展开";
            PreviewVisible = Visibility.Collapsed;
            ScanCache();
            InitPlaylist();

            //SelectedWallpaperInfo = WallpaperInfoCollection.Count > 0 ? WallpaperInfoCollection[0] : null;
        }

        #region Properties

        /// <summary>
        /// 壁纸列表
        /// </summary>
        public ObservableCollection<WallpaperInfo> WallpaperInfoCollection { get; private set; } = new ObservableCollection<WallpaperInfo>();

        public ObservableCollection<WallpaperInfo> PlayListCollection { get; private set; } = new ObservableCollection<WallpaperInfo>();

        /// <summary>
        /// 已选择壁纸
        /// </summary>
        private WallpaperInfo? _selectedWallpaperInfo;
        public WallpaperInfo? SelectedWallpaperInfo
        {
            get => _selectedWallpaperInfo;
            set
            {
                SetProperty(ref _selectedWallpaperInfo, value);
                if (_selectedWallpaperInfo != null)
                {
                    PreviewUrl = _selectedWallpaperInfo.PreviewPath;

                    //_windowEvent.Publish(new WindowEvent
                    //{
                    //    Data = new double[] { 450, 400 },
                    //    WindowActionType = WindowActionType.Edit,
                    //    EventId = EventIds.SetWindowSize,
                    //});
                    //_isExpend = true;
                }
            }
        }

        private int _lbSelectedIndex = 0;
        public int LbSelectedIndex { get => _lbSelectedIndex; set => SetProperty(ref _lbSelectedIndex, value); }

        private double _previewWidth;
        public double PreviewWidth { get => _previewWidth; set => SetProperty(ref _previewWidth, value); }

        private double _previewHeight;
        public double PreviewHeight { get => _previewHeight; set => SetProperty(ref _previewHeight, value); }


        private string _playBtnText = string.Empty;
        public string PlayBtnText
        {
            get => _playBtnText;
            set { SetProperty(ref _playBtnText, value); }
        }

        private string dropText = string.Empty;
        public string DropText { get => dropText; set => SetProperty(ref dropText, value); }

        /// <summary>
        /// 已选择壁纸路径
        /// </summary>
        private string _previewUrl = string.Empty;
        public string PreviewUrl { get => _previewUrl; set { SetProperty(ref _previewUrl, value); } }

        /// <summary>
        /// 预览图可见性
        /// </summary>
        private Visibility _previewVisible;
        public Visibility PreviewVisible { get => _previewVisible; set => SetProperty(ref _previewVisible, value); }

        private SettingConfig _settings;
        public SettingConfig Settings { get => _settings; set => SetProperty(ref _settings, value); }

        private Loading _loading = new Loading();
        public Loading Loading { get => _loading; set => SetProperty(ref _loading, value); }

        #endregion //Properties

        #region Commands

        /// <summary>
        /// 添加壁纸
        /// </summary>
        public ICommand AddWallpaperCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                Action<object> callback = r =>
                {
                    Action<Project> callback2 = r =>
                    {
                        ScanCache(r);
                        //SetWallpaper(r.Path);
                        //PreviewUrl = r.PreviewPath;
                        //SelectedWallpaperInfo = r;
                    };

                    if (r is Project project)
                    {
                        Task.Factory.StartNew(() =>
                        {
                            OnLoading(true);
                            PictureHelper.ConvertToBmp(ref project);
                            callback2(project);
                            OnLoading(false);
                        });
                    }
                    else if (r is Project[] projects)
                    {
                        Task.Factory.StartNew(() =>
                        {
                            OnLoading(true);
                            foreach (var item in projects)
                            {
                                var info = item;
                                PictureHelper.ConvertToBmp(ref info);
                                callback2(projects[projects.Length - 1]);
                            }
                            OnLoading(false);
                        });
                    }
                };

                _windowEvent.Publish(new WindowEvent
                {
                    Data = null,
                    CallBack = callback,
                    WindowActionType = WindowActionType.Open,
                    EventId = EventIds.OpenAddWindow,
                });
            });
        }

        /// <summary>
        /// 设置壁纸
        /// </summary>
        public ICommand SetWallpaperCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                if (SelectedWallpaperInfo != null)
                {
                    OnPlay(false);  //暂停播放
                    wallpaperManager.SetWallpaper(SelectedWallpaperInfo.Path);
                }
            });
        }

        /// <summary>
        /// 查看图片
        /// </summary>
        public ICommand ViewPictureCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                _windowEvent.Publish(new WindowEvent
                {
                    Data = SelectedWallpaperInfo?.Path ?? string.Empty,
                    WindowActionType = WindowActionType.Open,
                    EventId = EventIds.OpenViewPictureWindow,
                });
            });
        }

        /// <summary>
        /// 删除壁纸
        /// </summary>
        public ICommand DeletePictureCommand
        {
            get => new RelayCommand<WallpaperInfo>(fileInfo =>
            {
                var result = MessageBox.Show("确认删除壁纸？", "删除壁纸", MessageBoxButton.YesNo);
                if (result == MessageBoxResult.Yes)
                {
                    OnPlay(false);
                    var dir = fileInfo?.Dir;
                    if (Directory.Exists(dir))
                    {
                        Directory.Delete(dir, true);
                        ScanCache();
                        InitPlaylist();
                    }
                }
            });
        }

        /// <summary>
        /// 播放
        /// </summary>
        public ICommand LoopPlayCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                if (timer.Enabled == false)
                {
                    ChangeWallpaper(null, null);
                }
                OnPlay(!timer.Enabled);
            });
        }

        /// <summary>
        /// 展开/折叠窗口命令
        /// </summary>
        public ICommand ExpandWindowCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                if (_isExpend)
                {
                    PreviewVisible = Visibility.Collapsed;
                    _windowEvent.Publish(new WindowEvent
                    {
                        Data = new double[] { -1, 150 },
                        WindowActionType = WindowActionType.Edit,
                        EventId = EventIds.SetWindowSize,
                    });
                    DropText = "展开";
                    _isExpend = false;
                }
                else
                {
                    PreviewVisible = Visibility.Visible;
                    _windowEvent.Publish(new WindowEvent
                    {
                        Data = new double[] { -1, 400 },
                        WindowActionType = WindowActionType.Edit,
                        EventId = EventIds.SetWindowSize,
                    });
                    DropText = "折叠";
                    _isExpend = true;
                }
            });
        }

        /// <summary>
        /// 加入播放列表
        /// </summary>
        public ICommand AddPlayListCommand
        {
            get => new RelayCommand<WallpaperInfo>(obj =>
            {
                if (obj == null) return;

                timer.Enabled = false;
                PlayBtnText = "播放";

                lock (locker)
                    PlayListCollection.Add(obj);
            });
        }

        /// <summary>
        /// 移出播放列表
        /// </summary>
        public ICommand RemovePlayListCommand
        {
            get => new RelayCommand<WallpaperInfo>(obj =>
            {
                if (obj == null) return;
                lock (locker)
                    PlayListCollection.Remove(obj);
            });
        }

        /// <summary>
        /// 打开播放列表弹窗
        /// </summary>
        public ICommand ShowPlayListCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                _windowEvent.Publish(new WindowEvent
                {
                    WindowActionType = WindowActionType.Open,
                    EventId = EventIds.OpenPlayListPup,
                });
            });
        }

        public ICommand OpenSettingCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                _windowEvent.Publish(new WindowEvent
                {
                    WindowActionType = WindowActionType.Open,
                    EventId = EventIds.OpenSettings,
                });
            });
        }

        public ICommand ConfirmEditCommand
        {
            get => new RelayCommand<object>(obj =>
            {
                ConfigManager.Instance.Settings = Settings;
            });
        }


        #endregion //Commands

        #region Funcs

        /// <summary>
        /// 播放壁纸
        /// </summary>
        /// <param name="play"></param>
        private void OnPlay(bool play)
        {
            if (play)
            {
                timer.Interval = ConfigManager.Instance.Settings.PlaySetting.Interval * 1000;
                timer.Enabled = true;
                PlayBtnText = "暂停";
            }
            else
            {
                timer.Enabled = false;
                PlayBtnText = "播放";
            }
        }

        /// <summary>
        /// 轮播壁纸切换
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ChangeWallpaper(object? sender, ElapsedEventArgs? e)
        {
            lock (locker)
            {
                if (PlayListCollection.Count <= 0) return;

                var info = PlayListCollection[wp_index];
                wallpaperManager.SetWallpaper(info.Path);
            }
            wp_index++;
            wp_index %= PlayListCollection.Count;
        }

        /// <summary>
        /// 扫描壁纸资源文件夹
        /// </summary>
        /// <param name="path"></param>
        private async void ScanCache(Project? project = null)
        {
            await Task.Run(() =>
            {
                IList<WallpaperInfo> fileList = wallpaperManager.OnScanCache();

                Application.Current.Dispatcher.Invoke(() =>
                {
                    WallpaperInfoCollection.Clear();
                    foreach (var file in fileList)
                    {
                        WallpaperInfoCollection.Add(file);
                    }
                    if (project != null)
                    {
                        SelectedWallpaperInfo = WallpaperManager.ProjectToInfo(project);
                    }
                });
            });
        }

        /// <summary>
        /// 初始化播放列表
        /// </summary>
        private async void InitPlaylist()
        {
            await Task.Run(() =>
            {
                IList<WallpaperInfo> fileList = wallpaperManager.OnScanPlaylist();

                Application.Current.Dispatcher.Invoke(() =>
                {
                    PlayListCollection.Clear();
                    foreach (var file in fileList)
                    {
                        PlayListCollection.Add(file);
                    }
                });
            });
        }

        /// <summary>
        /// 保存播放壁纸
        /// </summary>
        private void SavePlayList()
        {
            string[] pl = PlayListCollection.Select(m => m.Dir).ToArray();
            ConfigManager.Instance.PlayList.Wallpapaers = pl;
        }


        /// <summary>
        /// 设置预览图
        /// </summary>
        /// <param name="picture"></param>
        /// <returns></returns>
        private string SetPreivewPicture(string picture)
        {
            ClearCache();

            string cacheDir = DomainHelper.GetDirectoryPath(DirectoryDefine.CACHE);
            string cacheName = Path.GetFileNameWithoutExtension(picture);
            string cachePath = Path.Combine(cacheDir, cacheName + FileExtension.BMP);
            //保存预览图片
            using (Bitmap bitmap = (Bitmap)Image.FromFile(picture))
            {
                Size size = new Size(50, 50 * bitmap.Height / bitmap.Width);
                using (Bitmap newBitmap = new Bitmap(bitmap, size))
                {
                    newBitmap.Save(cachePath, ImageFormat.Bmp);
                }
            }
            return cachePath;
        }

        private void OnLoading(bool load)
        {
            Loading.Message = "正在导入，请稍后...";
            Loading.Visible = load ? Visibility.Visible : Visibility.Collapsed;
        }

        private void ClearCache()
        {
            WallpaperInfoCollection.Clear();
            string cacheDir = DomainHelper.GetDirectoryPath(DirectoryDefine.CACHE);
            if (Directory.Exists(cacheDir))
            {
                Directory.Delete(cacheDir, true);
            }
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Release()
        {
            //ClearCache();
            timer.Dispose();
            SavePlayList();
        }

        #endregion //Funcs
    }
}
